package com.example.dishit.controller.main;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

import com.example.dishit.controller.recommendation.RecommendationListener;
import com.example.dishit.model.dish.DishData;
import com.example.dishit.service.dishpoll.DishPollingServiceFactory;
import com.example.dishit.service.recommendation.IRecommendationListener;
import com.example.dishit.service.recommendation.RecommendationGeneratorFactory;
import com.example.dishit.view.alert.AlertView;
import com.example.dishit.view.main.MainActivity;
import com.example.dishit.view.recommendation.RecommendationActivity;

public class MainController implements IMainController {
    private static final MainController instance = new MainController();
    public static final String THIS_USER_ID = "charan";
    private MainActivity view;
    
    private MainController() {}
    
    public static MainController instance() { return instance; }
    
    public void setView(final MainActivity view) {
        this.view = view;
        DishPollingServiceFactory.instance().start(view);
    }
    
    public void transition(final Bundle bundle,
                           final Class<? extends Activity> newState) {
        Intent intent = new Intent();
        intent.setClass(view, newState);
        intent.putExtras(bundle);
        view.startActivity(intent);
    }
    
    public void transition(final DishData dish,
                           final Class<? extends Activity> newState) {
        Intent intent = new Intent(view, RecommendationActivity.class);
        intent.putExtra(DishData.DISH_DATA_KEY, dish);
        view.startActivity(intent);
    }
    
    public void findRestaurant() {
        // Request a recommendation.
        final IRecommendationListener callback = new RecommendationListener(view, THIS_USER_ID);
        RecommendationGeneratorFactory.instance().requestRecommendation(callback);
    }
    
    public void addReceivedDish(final DishData dish) {
        view.runOnUiThread(new Runnable() {
            public void run() {
                view.addReceivedDish(dish);
            }
        });
    }
    
    public void addSentDish(final DishData dish) {
        view.runOnUiThread(new Runnable() {
            public void run() {
                view.addSentDish(dish);
            }
        });
    }
    
    public void setReceivedDishes(final List<DishData> dishes) {
        view.runOnUiThread(new Runnable() {
            public void run() {
                view.setReceivedDishes(dishes);
                
                // Draw the alerts for new dishes.
                for(final DishData dish : dishes) {
                    // If the DishData is new, then...
                    if(isDishNew(dish)) {
                        // Add it to list for later.
                        previousDishes.add(dish);
                        
                        // Display the alert.
                        AlertView.drawAlert(view,
                                dish.getRecommendedBy() + " dished:    " + dish.getRestaurantName(),
                                dish);
                    }
                }
            }
        });
    }
    
    // FIXME: This is a terrible way of doing it.  Should use time-stamps instead.
    // TODO: Put time-stamps into the Model/DB.
    private final List<DishData> previousDishes = new ArrayList<DishData>();
    private boolean isDishNew(final DishData newDish) {
        for(final DishData oldDish : previousDishes) {
            if(oldDish == null) continue;
            
            if(oldDish.getRestaurantName().equals(newDish.getRestaurantName())
                    && oldDish.getRecommendedBy().equals(newDish.getRecommendedBy())
                    && oldDish.getComments().equals(newDish.getComments())) {
                return false;
            }
        }
        return true;
    }
    
    public void setSentDishes(final List<DishData> dishes) {
        view.runOnUiThread(new Runnable() {
            public void run() {
                view.setSentDishes(dishes);
            }
        });
    }
}
